package org.wukongcrm.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecureDigestAlgorithm;

import javax.crypto.SecretKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * JWT工具类
 */
public class JwtUtils {
    //密钥字符串
    private static final String JWS_SECRET = "SFJOJWIEFJMSDFJISOJFOWOFMWOMEFOWEJFOIWEOFWOEFOWNEOFMON";
    //载荷Key
    private static final String JWS_BODY_KEY_NAME = "username";
    private static final String JWS_BODY_KEY_ID = "userId";
    private static final String JWS_BODY_KEY_AUTHORITY = "authority";
    //过期时间
    public static long EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 365;
    //加密方式
    private final static SecureDigestAlgorithm<SecretKey, SecretKey> ALGORITHM = Jwts.SIG.HS256;
    //密钥串
    public static final SecretKey KEY = Keys.hmacShaKeyFor(JWS_SECRET.getBytes());


    /**
     * 根据账户生成token
     * @param username
     * @return
     */
    public static String generateToken(String username) {
        Date exprireDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
        return Jwts.builder().header().add("typ", "JWT").
                and().claim(JWS_BODY_KEY_NAME, username)
                .expiration(exprireDate)
                .issuedAt(new Date())
                .signWith(KEY,ALGORITHM).compact();
    }

    /**
     * 根据账户和编号生成token
     * @param username
     * @return
     */
    public static String generateToken(Integer id,String username) {
        Date exprireDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
        return Jwts.builder().header().add("typ", "JWT").
                and().claim(JWS_BODY_KEY_NAME, username)
                .claim(JWS_BODY_KEY_ID, id)
                .expiration(exprireDate)
                .issuedAt(new Date())
                .signWith(KEY,ALGORITHM).compact();
    }

    /**
     * 根据账户和编号生成token
     * @param username
     * @return
     */
    public static String generateToken(Integer id, String username, List<String> authorities) {
        Date exprireDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
        return Jwts.builder().header().add("typ", "JWT").
                and().claim(JWS_BODY_KEY_NAME, username)
                .claim(JWS_BODY_KEY_ID, id)
                .claim(JWS_BODY_KEY_AUTHORITY, authorities)
                .expiration(exprireDate)
                .issuedAt(new Date())
                .signWith(KEY,ALGORITHM).compact();
    }

    /**
     * 根据token获取用户名称
     * @param token
     * @return
     */
    public static String getUsername(String token) {
        Claims payload = Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload();
        return payload.get(JWS_BODY_KEY_NAME).toString();
    }

    /**
     * 根据token获取用户编号
     * @param token
     * @return
     */
    public static Integer getId(String token) {
        Claims payload = Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload();
        return (Integer)payload.get(JWS_BODY_KEY_ID);
    }

    /**
     * 根据token获取用户权限
     *
     * @param token
     * @return
     */
    public static List<String> getAuthorities(String token) {
        Claims payload = Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload();
        return (List<String>) payload.get(JWS_BODY_KEY_AUTHORITY);
    }

    /**
     * 判断token是否过期
     * session
     * @param token
     * @return
     */
    public static boolean isExpired(String token) {
        try {
            Claims payload = Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload();
            return payload.getExpiration().before(new Date());
        } catch (JwtException e) {
        } catch (IllegalArgumentException e) {
        }
        return true;
    }

    public static void main(String[] args) {
        List<String> authorities = new ArrayList<>();
        authorities.add("ROLE_ADMIN");
        authorities.add("ROLE_USER");
        authorities.add("ROLE_ROOT");
        String token = generateToken(1,"admin",authorities);
        String username = getUsername(token);
        List<String> authorities1 = getAuthorities(token);
        System.out.println(authorities1.get(1));
        System.out.println(token);
    }
}
